#include "precompiled.h"
#include "frostmage.h"
using namespace std;
using namespace weo::engine::item;
using namespace weo::engine::character::mage;

Frost::Frost()
{
    Casterdps::Init();
    m_Classnr = weo::engine::character::Character::isAllowed("Mage");
    m_Basevalues.push_back(Attribute("Agility",37));
    m_Basevalues.push_back(Attribute("Intellect",149));
    m_Basevalues.push_back(Attribute("Strength",32));
    m_Basevalues.push_back(Attribute("Stamina",52));
    m_Basevalues.push_back(Attribute("Spirit",150));
    m_Basevalues.push_back(Attribute("Health",3213)); // health
    m_Basevalues.push_back(Attribute("Mana",1961)); // mana
    // talents
    // talents
    m_Basevalues.push_back(Attribute("HitSpellRating",3.0f*HitSpellRating));
    m_Basevalues.push_back(Attribute("CritSpellRating",8.0f*CritSpellRating)); // 5 emp. fb, 3 molten armor
    m_Basevalues.push_back(Attribute("MP5", 46.6f)); // mana gems
    m_Equip.Mode(0);
    BOOST_FOREACH(Attribute attr, m_Basevalues)
    {
        handleAttribute(attr);
    }
    // base settings finished
    Buff *puredeath = new Buff("Flask of Pure Death");
    puredeath->addAttribute(Attribute("ShadowSpellDamage", 80));
    puredeath->addAttribute(Attribute("FireSpellDamage", 80));
    puredeath->addAttribute(Attribute("FrostSpellDamage", 80));
    m_Buffs[puredeath->Name()] = *puredeath;
}
// mana, int, spirit, spelldmg, spellcrit, spellhit, spellhaste,mp5,health
// simplified 5 scorch, 7 fb
float Frost::evaluateTF()
{
    float runtime = 600;
    float time = runtime;
    float mana = m_Equip[35];
    float intellect = m_Equip[2];
    float spirit = m_Equip[5];
    float spelldmg = m_Equip[23] + m_Equip[26]; // normal + Frostspelldmg
    float crit = m_Equip[12] / CritSpellRating;
    float hit = m_Equip[11] / HitSpellRating;
    hit = min<float>(83.0f + hit, 99);
    float haste = m_Equip[13] / HasteSpellRating;
    float mp5 = m_Equip[21];
    float fbcastspeed = max<float>(2.5f/(1+haste/100),1.5f);
    float wchill = min<float>(15.0f/((5/(hit/100.0f))*fbcastspeed),1.0f)*10.0f;
    crit += wchill;
    if(m_Equip.hasSpecial(134873)) // eye of magtheridon
    {
        float eyebonus = (10/fbcastspeed)*((100-hit)/100.0f)*(170.0f/10.0f);
        spelldmg += eyebonus;
    }
    float fbcritmult = 1.0f;
    if(m_Equip.hasSpecial(445202)) // chaos metagem
    {
        fbcritmult *= 1.03f;
    }
    if(m_Equip.hasSpecial(1254409))
    {
        spelldmg += min<float>(1.0f,(30.0f/fbcastspeed)*(crit/100)*0.2f) * (190.0f/4.0f);
    }
    float fbdmg = (1+crit/100) * fbcritmult * 1.05f * 1.06f * ((3.0f/3.5f + 0.1f) * spelldmg + 766.0f);
    if(m_Equip.hasSpecial(1256673)) // t6 2p
    {
        fbdmg *= 1.05f;
    }
    float evoticks = 4;
    if(m_Equip.hasSpecial(1425492)) // t6 2p
    {
        evoticks += 1;
    }
    float evocation = 0.15f * evoticks * mana * (runtime / (8 * 60));
    float manaregooc = ((spirit / 4.0f + 12.5f) * 2.5f + mp5)/5;
    float fbmana = 0.97f * 0.85f * 0.9f * 345 - (mp5/5) * fbcastspeed - evocation/(8*60/fbcastspeed);
    float count = floor(mana/fbmana);
    float castuseratio = (manaregooc * fbcastspeed) / fbmana;
    time -= count * fbcastspeed + max<float>(5 * castuseratio, 5) - (runtime/(8*60));
    time = max<float>(time, 0);
    if(time > 0)
    {
        float regtime = time / (castuseratio + 1);
        time -= regtime;
    }
    count += floor(time / fbcastspeed);
    count = min<float>(count, runtime / fbcastspeed);
    float finaldmg = count * (hit/100.0f) * fbdmg;
    return m_CondFactor * finaldmg/runtime;
}
void Frost::filterEquip(std::vector<std::vector<const weo::engine::item::Item*>>& items)
{
    for(unsigned int i = 0;i<10;i++)
    {
        int subtype = 3;
        if(i == 1 || i == 3)
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1);
            items.push_back(temp);
        }
        else
        {
            vector<const Item*> temp = m_Database->getPtrbyType(1,i+1,1); // cloth	
            items.push_back(temp);
        }
    }
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(2,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    items.push_back(m_Database->getPtrbyType(3,0));
    // main hand weapons
    vector<const Item*> mainhand;
    for(int j = 1;j<3;j++)
    {
        vector<const Item*> weapon = m_Database->getPtrbyType(4,j,1);
        vector<const Item*>::iterator it;
        for(it=weapon.begin();it!=weapon.end();it++)
        {
            mainhand.push_back(*it);
        }
    }
    for(int j = 1;j<3;j++)
    {
        vector<const Item*> weapon = m_Database->getPtrbyType(4,j,5);
        vector<const Item*>::iterator it;
        for(it=weapon.begin();it!=weapon.end();it++)
        {
            mainhand.push_back(*it);
        }
    }
    // staff
    vector<const Item*> staff = m_Database->getPtrbyType(4,4,6);
    vector<const Item*>::iterator it;
    for(it=staff.begin();it!=staff.end();it++)
    {
        mainhand.push_back(*it);
    }
    // off hand weapons
    vector<const Item*> offhand = m_Database->getPtrbyType(1,12);
    items.push_back(mainhand);
    items.push_back(offhand);
    items.push_back(m_Database->getPtrbyType(4,5,13)); // wands
    items.push_back(m_Database->getPtrbyType(5,0));
    Casterdps::filterEquip(items);
}
void Frost::handleAttribute(const Attribute& attr)
{
    switch(attr.Type())
    {		
    default:
        Casterdps::handleAttribute(attr);
        break;
    }
}
